package fi.tikesos.validator.jena.builtin;

import com.hp.hpl.jena.datatypes.DatatypeFormatException;
import com.hp.hpl.jena.datatypes.RDFDatatype;
import com.hp.hpl.jena.datatypes.TypeMapper;
import com.hp.hpl.jena.graph.Node;
import com.hp.hpl.jena.graph.impl.LiteralLabelFactory;
import com.hp.hpl.jena.reasoner.rulesys.BindingEnvironment;
import com.hp.hpl.jena.reasoner.rulesys.RuleContext;
import com.hp.hpl.jena.reasoner.rulesys.builtins.BaseBuiltin;

public class CastAsBuiltin extends BaseBuiltin {
	/**
	 * (non-Javadoc)
	 * 
	 * @see com.hp.hpl.jena.reasoner.rulesys.Builtin#getName()
	 */
	public String getName() {
		return "castAs";
	}

	/**
	 * (non-Javadoc)
	 * 
	 * @see com.hp.hpl.jena.reasoner.rulesys.builtins.BaseBuiltin#getArgLength()
	 */
	public int getArgLength() {
		return 3;
	}

	/**
	 * (non-Javadoc)
	 * 
	 * @see com.hp.hpl.jena.reasoner.rulesys.builtins.BaseBuiltin#bodyCall(com.hp.hpl.jena.graph.Node[],
	 *      int, com.hp.hpl.jena.reasoner.rulesys.RuleContext)
	 */
	public boolean bodyCall(Node[] args, int length, RuleContext context) {
		checkArgs(length, context);
		BindingEnvironment env = context.getEnv();
		Node value = getArg(1, args, context);

		if (value.isLiteral()) {
			Node type = getArg(2, args, context);
			RDFDatatype dtype = TypeMapper.getInstance().getSafeTypeByName(
					type.getURI());
			if (value.getLiteralDatatypeURI() == dtype.getURI()) {
				return env.bind(args[0], value);
			} else {
				Object literal = value.getLiteralValue();

				try {
					Node n = Node.createLiteral(LiteralLabelFactory
							.create(dtype.parse(literal.toString())));
					return env.bind(args[0], n);
				} catch (DatatypeFormatException e) {
					return false;
				}
			}
		}
		return false;
	}
}
